home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / points.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  27KB  |  937 lines

  1. /* $Id: points.c,v 3.5 1998/07/29 04:08:09 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: points.c,v $
  26.  * Revision 3.5  1998/07/29 04:08:09  brianp
  27.  * feedback returned wrong point color
  28.  *
  29.  * Revision 3.4  1998/06/07 22:18:52  brianp
  30.  * implemented GL_EXT_multitexture extension
  31.  *
  32.  * Revision 3.3  1998/03/27 04:17:31  brianp
  33.  * fixed G++ warnings
  34.  *
  35.  * Revision 3.2  1998/02/08 20:19:12  brianp
  36.  * removed unneeded headers
  37.  *
  38.  * Revision 3.1  1998/02/04 00:44:29  brianp
  39.  * fixed casts and conditional expression problems for Amiga StormC compiler
  40.  *
  41.  * Revision 3.0  1998/01/31 21:01:27  brianp
  42.  * initial rev
  43.  *
  44.  */
  45.  
  46.  
  47. #ifdef PC_HEADER
  48. #include "all.h"
  49. #else
  50. #include "context.h"
  51. #include "feedback.h"
  52. #include "macros.h"
  53. #include "pb.h"
  54. #include "span.h"
  55. #include "texstate.h"
  56. #include "types.h"
  57. #include "vb.h"
  58. #include "mmath.h"
  59. #endif
  60.  
  61.  
  62.  
  63. void gl_PointSize( GLcontext *ctx, GLfloat size )
  64. {
  65.    if (size<=0.0) {
  66.       gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
  67.       return;
  68.    }
  69.    if (INSIDE_BEGIN_END(ctx)) {
  70.       gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" );
  71.       return;
  72.    }
  73.    ctx->Point.Size = size;
  74.    ctx->NewState |= NEW_RASTER_OPS;
  75. }
  76.  
  77.  
  78.  
  79. void gl_PointParameterfvEXT( GLcontext *ctx, GLenum pname,
  80.                                     const GLfloat *params)
  81. {
  82.    if (INSIDE_BEGIN_END(ctx)) {
  83.       gl_error( ctx, GL_INVALID_OPERATION, "glPointParameterfvEXT" );
  84.       return;
  85.    }
  86.    if(pname==GL_DISTANCE_ATTENUATION_EXT) {
  87.          COPY_3V(ctx->Point.Params,params);
  88.    } else {
  89.         if (*params<0.0 ) {
  90.             gl_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" );
  91.             return;
  92.         }
  93.         switch (pname) {
  94.             case GL_POINT_SIZE_MIN_EXT:
  95.                 ctx->Point.MinSize=*params;
  96.                 break;
  97.             case GL_POINT_SIZE_MAX_EXT:
  98.                 ctx->Point.MaxSize=*params;
  99.                 break;
  100.             case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
  101.                 ctx->Point.Threshold=*params;
  102.                 break;
  103.             default:
  104.                 gl_error( ctx, GL_INVALID_ENUM, "glPointParameterfvEXT" );
  105.                 return;
  106.         }
  107.    }
  108.    ctx->NewState |= NEW_RASTER_OPS;
  109. }
  110.  
  111.  
  112. /**********************************************************************/
  113. /*****                    Rasterization                           *****/
  114. /**********************************************************************/
  115.  
  116.  
  117. /*
  118.  * There are 3 pairs (RGBA, CI) of point rendering functions:
  119.  *   1. simple:  size=1 and no special rasterization functions (fastest)
  120.  *   2. size1:  size=1 and any rasterization functions
  121.  *   3. general:  any size and rasterization functions (slowest)
  122.  *
  123.  * All point rendering functions take the same two arguments: first and
  124.  * last which specify that the points specified by VB[first] through
  125.  * VB[last] are to be rendered.
  126.  */
  127.  
  128.  
  129.  
  130. /*
  131.  * Put points in feedback buffer.
  132.  */
  133. static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
  134. {
  135.    struct vertex_buffer *VB = ctx->VB;
  136.    GLuint texSet = ctx->Texture.CurrentTransformSet;
  137.    GLuint i;
  138.  
  139.    for (i=first;i<=last;i++) {
  140.       if (VB->ClipMask[i]==0) {
  141.          GLfloat x, y, z, w, invq;
  142.          GLfloat color[4], texcoord[4];
  143.          x = VB->Win[i][0];
  144.          y = VB->Win[i][1];
  145.          z = VB->Win[i][2] / DEPTH_SCALE;
  146.          w = VB->Clip[i][3];
  147.  
  148.          /* convert color from integer back to a float in [0,1] */
  149.          color[0] = VB->Color[i][0] * (1.0F / 255.0F);
  150.          color[1] = VB->Color[i][1] * (1.0F / 255.0F);
  151.          color[2] = VB->Color[i][2] * (1.0F / 255.0F);
  152.          color[3] = VB->Color[i][3] * (1.0F / 255.0F);
  153.  
  154.          invq = 1.0F / VB->MultiTexCoord[texSet][i][3];
  155.          texcoord[0] = VB->MultiTexCoord[texSet][i][0] * invq;
  156.          texcoord[1] = VB->MultiTexCoord[texSet][i][1] * invq;
  157.          texcoord[2] = VB->MultiTexCoord[texSet][i][2] * invq;
  158.          texcoord[3] = VB->MultiTexCoord[texSet][i][3];
  159.  
  160.          FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
  161.          gl_feedback_vertex( ctx, x, y, z, w, color,
  162.                              (GLfloat) VB->Index[i], texcoord );
  163.       }
  164.    }
  165. }
  166.  
  167.  
  168.  
  169. /*
  170.  * Put points in selection buffer.
  171.  */
  172. static void select_points( GLcontext *ctx, GLuint first, GLuint last )
  173. {
  174.    struct vertex_buffer *VB = ctx->VB;
  175.    GLuint i;
  176.  
  177.    for (i=first;i<=last;i++) {
  178.       if (VB->ClipMask[i]==0) {
  179.          gl_update_hitflag( ctx, VB->Win[i][2] / DEPTH_SCALE );
  180.       }
  181.    }
  182. }
  183.  
  184.  
  185. /*
  186.  * CI points with size == 1.0
  187.  */
  188. void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  189. {
  190.    struct vertex_buffer *VB = ctx->VB;
  191.    struct pixel_buffer *PB = ctx->PB;
  192.    GLfloat *win;
  193.    GLint *pbx = PB->x, *pby = PB->y;
  194.    GLdepth *pbz = PB->z;
  195.    GLuint *pbi = PB->i;
  196.    GLuint pbcount = PB->count;
  197.    GLuint i;
  198.  
  199.    win = &VB->Win[first][0];
  200.    for (i=first;i<=last;i++) {
  201.       if (VB->ClipMask[i]==0) {
  202.          pbx[pbcount] = (GLint)  win[0];
  203.          pby[pbcount] = (GLint)  win[1];
  204.          pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
  205.          pbi[pbcount] = VB->Index[i];
  206.          pbcount++;
  207.       }
  208.       win += 3;
  209.    }
  210.    PB->count = pbcount;
  211.    PB_CHECK_FLUSH(ctx, PB)
  212. }
  213.  
  214.  
  215.  
  216. /*
  217.  * RGBA points with size == 1.0
  218.  */
  219. static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  220. {
  221.    struct vertex_buffer *VB = ctx->VB;
  222.    struct pixel_buffer *PB = ctx->PB;
  223.    GLuint i;
  224.  
  225.    for (i=first;i<=last;i++) {
  226.       if (VB->ClipMask[i]==0) {
  227.          GLint x, y, z;
  228.          GLint red, green, blue, alpha;
  229.  
  230.          x = (GLint)  VB->Win[i][0];
  231.          y = (GLint)  VB->Win[i][1];
  232.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  233.  
  234.          red   = VB->Color[i][0];
  235.          green = VB->Color[i][1];
  236.          blue  = VB->Color[i][2];
  237.          alpha = VB->Color[i][3];
  238.  
  239.          PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  240.       }
  241.    }
  242.    PB_CHECK_FLUSH(ctx,PB)
  243. }
  244.  
  245.  
  246.  
  247. /*
  248.  * General CI points.
  249.  */
  250. static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
  251. {
  252.    struct vertex_buffer *VB = ctx->VB;
  253.    struct pixel_buffer *PB = ctx->PB;
  254.    GLuint i;
  255.    GLint isize;
  256.  
  257.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  258.  
  259.    for (i=first;i<=last;i++) {
  260.       if (VB->ClipMask[i]==0) {
  261.          GLint x, y, z;
  262.          GLint x0, x1, y0, y1;
  263.          GLint ix, iy;
  264.  
  265.          x = (GLint)  VB->Win[i][0];
  266.          y = (GLint)  VB->Win[i][1];
  267.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  268.  
  269.          if (isize&1) {
  270.             /* odd size */
  271.             x0 = x - isize/2;
  272.             x1 = x + isize/2;
  273.             y0 = y - isize/2;
  274.             y1 = y + isize/2;
  275.          }
  276.          else {
  277.             /* even size */
  278.             x0 = (GLint) (x + 0.5F) - isize/2;
  279.             x1 = x0 + isize-1;
  280.             y0 = (GLint) (y + 0.5F) - isize/2;
  281.             y1 = y0 + isize-1;
  282.          }
  283.  
  284.          PB_SET_INDEX( ctx, PB, VB->Index[i] );
  285.  
  286.          for (iy=y0;iy<=y1;iy++) {
  287.             for (ix=x0;ix<=x1;ix++) {
  288.                PB_WRITE_PIXEL( PB, ix, iy, z );
  289.             }
  290.          }
  291.          PB_CHECK_FLUSH(ctx,PB)
  292.       }
  293.    }
  294. }
  295.  
  296.  
  297. /*
  298.  * General RGBA points.
  299.  */
  300. static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  301. {
  302.    struct vertex_buffer *VB = ctx->VB;
  303.    struct pixel_buffer *PB = ctx->PB;
  304.    GLuint i;
  305.    GLint isize;
  306.  
  307.    isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  308.  
  309.    for (i=first;i<=last;i++) {
  310.       if (VB->ClipMask[i]==0) {
  311.          GLint x, y, z;
  312.          GLint x0, x1, y0, y1;
  313.          GLint ix, iy;
  314.  
  315.          x = (GLint)  VB->Win[i][0];
  316.          y = (GLint)  VB->Win[i][1];
  317.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  318.  
  319.          if (isize&1) {
  320.             /* odd size */
  321.             x0 = x - isize/2;
  322.             x1 = x + isize/2;
  323.             y0 = y - isize/2;
  324.             y1 = y + isize/2;
  325.          }
  326.          else {
  327.             /* even size */
  328.             x0 = (GLint) (x + 0.5F) - isize/2;
  329.             x1 = x0 + isize-1;
  330.             y0 = (GLint) (y + 0.5F) - isize/2;
  331.             y1 = y0 + isize-1;
  332.          }
  333.  
  334.          PB_SET_COLOR( ctx, PB,
  335.                        VB->Color[i][0],
  336.                        VB->Color[i][1],
  337.                        VB->Color[i][2],
  338.                        VB->Color[i][3] );
  339.  
  340.          for (iy=y0;iy<=y1;iy++) {
  341.             for (ix=x0;ix<=x1;ix++) {
  342.                PB_WRITE_PIXEL( PB, ix, iy, z );
  343.             }
  344.          }
  345.          PB_CHECK_FLUSH(ctx,PB)
  346.       }
  347.    }
  348. }
  349.  
  350.  
  351.  
  352.  
  353. /*
  354.  * Textured RGBA points.
  355.  */
  356. static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
  357. {
  358.    struct vertex_buffer *VB = ctx->VB;
  359.    struct pixel_buffer *PB = ctx->PB;
  360.    GLuint i;
  361.  
  362.    for (i=first;i<=last;i++) {
  363.       if (VB->ClipMask[i]==0) {
  364.          GLint x, y, z;
  365.          GLint x0, x1, y0, y1;
  366.          GLint ix, iy;
  367.          GLint isize;
  368.          GLint red, green, blue, alpha;
  369.          GLfloat s, t, u;
  370.  
  371.          x = (GLint)  VB->Win[i][0];
  372.          y = (GLint)  VB->Win[i][1];
  373.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  374.  
  375.          isize = (GLint)
  376.                    (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
  377.          if (isize<1) {
  378.             isize = 1;
  379.          }
  380.  
  381.          if (isize&1) {
  382.             /* odd size */
  383.             x0 = x - isize/2;
  384.             x1 = x + isize/2;
  385.             y0 = y - isize/2;
  386.             y1 = y + isize/2;
  387.          }
  388.          else {
  389.             /* even size */
  390.             x0 = (GLint) (x + 0.5F) - isize/2;
  391.             x1 = x0 + isize-1;
  392.             y0 = (GLint) (y + 0.5F) - isize/2;
  393.             y1 = y0 + isize-1;
  394.          }
  395.  
  396.          red   = VB->Color[i][0];
  397.          green = VB->Color[i][1];
  398.          blue  = VB->Color[i][2];
  399.          alpha = VB->Color[i][3];
  400.          s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  401.          t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  402.          u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  403.  
  404. /*    don't think this is needed
  405.          PB_SET_COLOR( red, green, blue, alpha );
  406. */
  407.  
  408.          for (iy=y0;iy<=y1;iy++) {
  409.             for (ix=x0;ix<=x1;ix++) {
  410.                PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t, u );
  411.             }
  412.          }
  413.          PB_CHECK_FLUSH(ctx,PB)
  414.       }
  415.    }
  416. }
  417.  
  418.  
  419.  
  420. /*
  421.  * Antialiased points with or without texture mapping.
  422.  */
  423. static void antialiased_rgba_points( GLcontext *ctx,
  424.                                      GLuint first, GLuint last )
  425. {
  426.    struct vertex_buffer *VB = ctx->VB;
  427.    struct pixel_buffer *PB = ctx->PB;
  428.    GLuint i;
  429.    GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
  430.  
  431.    radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
  432.    rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  433.    rmax = radius + 0.7071F;
  434.    rmin2 = rmin*rmin;
  435.    rmax2 = rmax*rmax;
  436.    cscale = 256.0F / (rmax2-rmin2);
  437.  
  438.    if (ctx->Texture.Enabled) {
  439.       for (i=first;i<=last;i++) {
  440.          if (VB->ClipMask[i]==0) {
  441.             GLint xmin, ymin, xmax, ymax;
  442.             GLint x, y, z;
  443.             GLint red, green, blue, alpha;
  444.             GLfloat s, t, u;
  445.  
  446.             xmin = (GLint) (VB->Win[i][0] - radius);
  447.             xmax = (GLint) (VB->Win[i][0] + radius);
  448.             ymin = (GLint) (VB->Win[i][1] - radius);
  449.             ymax = (GLint) (VB->Win[i][1] + radius);
  450.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  451.  
  452.             red   = VB->Color[i][0];
  453.             green = VB->Color[i][1];
  454.             blue  = VB->Color[i][2];
  455.             s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  456.             t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  457.             u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  458.  
  459.             for (y=ymin;y<=ymax;y++) {
  460.                for (x=xmin;x<=xmax;x++) {
  461.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  462.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  463.                   GLfloat dist2 = dx*dx + dy*dy;
  464.                   if (dist2<rmax2) {
  465.                      alpha = VB->Color[i][3];
  466.                      if (dist2>=rmin2) {
  467.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  468.                         /* coverage is in [0,256] */
  469.                         alpha = (alpha * coverage) >> 8;
  470.                      }
  471.                      PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s, t, u );
  472.                   }
  473.                }
  474.             }
  475.             PB_CHECK_FLUSH(ctx,PB)
  476.          }
  477.       }
  478.    }
  479.    else {
  480.       /* Not texture mapped */
  481.       for (i=first;i<=last;i++) {
  482.          if (VB->ClipMask[i]==0) {
  483.             GLint xmin, ymin, xmax, ymax;
  484.             GLint x, y, z;
  485.             GLint red, green, blue, alpha;
  486.  
  487.             xmin = (GLint) (VB->Win[i][0] - radius);
  488.             xmax = (GLint) (VB->Win[i][0] + radius);
  489.             ymin = (GLint) (VB->Win[i][1] - radius);
  490.             ymax = (GLint) (VB->Win[i][1] + radius);
  491.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  492.  
  493.             red   = VB->Color[i][0];
  494.             green = VB->Color[i][1];
  495.             blue  = VB->Color[i][2];
  496.  
  497.             for (y=ymin;y<=ymax;y++) {
  498.                for (x=xmin;x<=xmax;x++) {
  499.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  500.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  501.                   GLfloat dist2 = dx*dx + dy*dy;
  502.                   if (dist2<rmax2) {
  503.                      alpha = VB->Color[i][3];
  504.                      if (dist2>=rmin2) {
  505.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  506.                         /* coverage is in [0,256] */
  507.                         alpha = (alpha * coverage) >> 8;
  508.                      }
  509.                      PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
  510.                   }
  511.                }
  512.             }
  513.             PB_CHECK_FLUSH(ctx,PB)
  514.          }
  515.       }
  516.    }
  517. }
  518.  
  519.  
  520.  
  521. /*
  522.  * Null rasterizer for measuring transformation speed.
  523.  */
  524. static void null_points( GLcontext *ctx, GLuint first, GLuint last )
  525. {
  526.    (void) ctx;
  527.    (void) first;
  528.    (void) last;
  529. }
  530.  
  531.  
  532.  
  533. /* Definition of the functions for GL_EXT_point_parameters */
  534.  
  535. /*
  536.  * Calculates the distance attenuation formula of a point in eye space
  537.  * coordinates
  538.  */
  539. static GLfloat dist_attenuation(GLcontext *ctx, const GLfloat p[3])
  540. {
  541.  GLfloat dist;
  542.  dist=GL_SQRT(p[0]*p[0]+p[1]*p[1]+p[2]*p[2]);
  543.  return (1/(ctx->Point.Params[0]+ ctx->Point.Params[1]*dist +
  544.              ctx->Point.Params[2]*dist*dist));
  545. }
  546.  
  547. /*
  548.  * Distance Attenuated General CI points.
  549.  */
  550. static void dist_atten_general_ci_points( GLcontext *ctx, GLuint first, 
  551.                     GLuint last )
  552. {
  553.    struct vertex_buffer *VB = ctx->VB;
  554.    struct pixel_buffer *PB = ctx->PB;
  555.    GLuint i;
  556.    GLint isize;
  557.    GLfloat psize,dsize;
  558.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  559.  
  560.    for (i=first;i<=last;i++) {
  561.       if (VB->ClipMask[i]==0) {
  562.          GLint x, y, z;
  563.          GLint x0, x1, y0, y1;
  564.          GLint ix, iy;
  565.  
  566.          x = (GLint)  VB->Win[i][0];
  567.          y = (GLint)  VB->Win[i][1];
  568.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  569.  
  570.          dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  571.          if(dsize>=ctx->Point.Threshold) {
  572.             isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  573.          } else {
  574.             isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  575.          }
  576.  
  577.          if (isize&1) {
  578.             /* odd size */
  579.             x0 = x - isize/2;
  580.             x1 = x + isize/2;
  581.             y0 = y - isize/2;
  582.             y1 = y + isize/2;
  583.          }
  584.          else {
  585.             /* even size */
  586.             x0 = (GLint) (x + 0.5F) - isize/2;
  587.             x1 = x0 + isize-1;
  588.             y0 = (GLint) (y + 0.5F) - isize/2;
  589.             y1 = y0 + isize-1;
  590.          }
  591.  
  592.          PB_SET_INDEX( ctx, PB, VB->Index[i] );
  593.  
  594.          for (iy=y0;iy<=y1;iy++) {
  595.             for (ix=x0;ix<=x1;ix++) {
  596.                PB_WRITE_PIXEL( PB, ix, iy, z );
  597.             }
  598.          }
  599.          PB_CHECK_FLUSH(ctx,PB)
  600.       }
  601.    }
  602. }
  603.  
  604. /*
  605.  * Distance Attenuated General RGBA points.
  606.  */
  607. static void dist_atten_general_rgba_points( GLcontext *ctx, GLuint first, 
  608.                 GLuint last )
  609. {
  610.    struct vertex_buffer *VB = ctx->VB;
  611.    struct pixel_buffer *PB = ctx->PB;
  612.    GLuint i;
  613.    GLubyte alpha;
  614.    GLint isize;
  615.    GLfloat psize,dsize;
  616.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  617.  
  618.    for (i=first;i<=last;i++) {
  619.       if (VB->ClipMask[i]==0) {
  620.          GLint x, y, z;
  621.          GLint x0, x1, y0, y1;
  622.          GLint ix, iy;
  623.  
  624.          x = (GLint)  VB->Win[i][0];
  625.          y = (GLint)  VB->Win[i][1];
  626.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  627.          dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  628.          if (dsize >= ctx->Point.Threshold) {
  629.             isize = (GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  630.             alpha = VB->Color[i][3];
  631.          }
  632.          else {
  633.             isize = (GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  634.             dsize /= ctx->Point.Threshold;
  635.             alpha = (GLint) (VB->Color[i][3]* (dsize*dsize));
  636.          }
  637.          if (isize & 1) {
  638.             /* odd size */
  639.             x0 = x - isize/2;
  640.             x1 = x + isize/2;
  641.             y0 = y - isize/2;
  642.             y1 = y + isize/2;
  643.          }
  644.          else {
  645.             /* even size */
  646.             x0 = (GLint) (x + 0.5F) - isize/2;
  647.             x1 = x0 + isize-1;
  648.             y0 = (GLint) (y + 0.5F) - isize/2;
  649.             y1 = y0 + isize-1;
  650.          }
  651.          PB_SET_COLOR( ctx, PB,
  652.                        VB->Color[i][0],
  653.                        VB->Color[i][1],
  654.                        VB->Color[i][2],
  655.                        alpha );
  656.  
  657.          for (iy=y0;iy<=y1;iy++) {
  658.             for (ix=x0;ix<=x1;ix++) {
  659.                PB_WRITE_PIXEL( PB, ix, iy, z );
  660.             }
  661.          }
  662.          PB_CHECK_FLUSH(ctx,PB)
  663.       }
  664.    }
  665. }
  666.  
  667. /*
  668.  *  Distance Attenuated Textured RGBA points.
  669.  */
  670. static void dist_atten_textured_rgba_points( GLcontext *ctx, GLuint first, 
  671.                     GLuint last )
  672. {
  673.    struct vertex_buffer *VB = ctx->VB;
  674.    struct pixel_buffer *PB = ctx->PB;
  675.    GLuint i;
  676.    GLfloat psize,dsize;
  677.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  678.  
  679.    for (i=first;i<=last;i++) {
  680.       if (VB->ClipMask[i]==0) {
  681.          GLint x, y, z;
  682.          GLint x0, x1, y0, y1;
  683.          GLint ix, iy;
  684.          GLint isize;
  685.          GLint red, green, blue, alpha;
  686.          GLfloat s, t, u;
  687.  
  688.          x = (GLint)  VB->Win[i][0];
  689.          y = (GLint)  VB->Win[i][1];
  690.          z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  691.  
  692.          dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  693.          if(dsize>=ctx->Point.Threshold) {
  694.             isize=(GLint) (MIN2(dsize,ctx->Point.MaxSize)+0.5F);
  695.             alpha=VB->Color[i][3];
  696.          } else {
  697.             isize=(GLint) (MAX2(ctx->Point.Threshold,ctx->Point.MinSize)+0.5F);
  698.             dsize/=ctx->Point.Threshold;
  699.             alpha = (GLint) (VB->Color[i][3]* (dsize*dsize));
  700.          }
  701.  
  702.          if (isize<1) {
  703.             isize = 1;
  704.          }
  705.  
  706.          if (isize&1) {
  707.             /* odd size */
  708.             x0 = x - isize/2;
  709.             x1 = x + isize/2;
  710.             y0 = y - isize/2;
  711.             y1 = y + isize/2;
  712.          }
  713.          else {
  714.             /* even size */
  715.             x0 = (GLint) (x + 0.5F) - isize/2;
  716.             x1 = x0 + isize-1;
  717.             y0 = (GLint) (y + 0.5F) - isize/2;
  718.             y1 = y0 + isize-1;
  719.          }
  720.  
  721.          red   = VB->Color[i][0];
  722.          green = VB->Color[i][1];
  723.          blue  = VB->Color[i][2];
  724.          s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  725.          t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  726.          u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  727.  
  728. /*    don't think this is needed
  729.          PB_SET_COLOR( red, green, blue, alpha );
  730. */
  731.   
  732.          for (iy=y0;iy<=y1;iy++) {
  733.             for (ix=x0;ix<=x1;ix++) {
  734.                PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t,
  735.  u );
  736.             }
  737.          }
  738.          PB_CHECK_FLUSH(ctx,PB)
  739.       }
  740.    }
  741. }
  742.  
  743. /*
  744.  * Distance Attenuated Antialiased points with or without texture mapping.
  745.  */
  746. static void dist_atten_antialiased_rgba_points( GLcontext *ctx,
  747.                                      GLuint first, GLuint last )
  748. {
  749.    struct vertex_buffer *VB = ctx->VB;
  750.    struct pixel_buffer *PB = ctx->PB;
  751.    GLuint i;
  752.    GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
  753.    GLfloat psize,dsize,alphaf;
  754.    psize=CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE);
  755.  
  756.    if (ctx->Texture.Enabled) {
  757.       for (i=first;i<=last;i++) {
  758.          if (VB->ClipMask[i]==0) {
  759.             GLint xmin, ymin, xmax, ymax;
  760.             GLint x, y, z;
  761.             GLint red, green, blue, alpha;
  762.             GLfloat s, t, u;
  763.  
  764.  
  765.             dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  766.             if(dsize>=ctx->Point.Threshold) {
  767.                radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
  768.                alphaf=1.0;
  769.             } else {
  770.                radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
  771.                dsize/=ctx->Point.Threshold;
  772.                alphaf=(dsize*dsize);
  773.             }
  774.             rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  775.             rmax = radius + 0.7071F;
  776.             rmin2 = rmin*rmin;
  777.             rmax2 = rmax*rmax;
  778.             cscale = 256.0F / (rmax2-rmin2);
  779.  
  780.             xmin = (GLint) (VB->Win[i][0] - radius);
  781.             xmax = (GLint) (VB->Win[i][0] + radius);
  782.             ymin = (GLint) (VB->Win[i][1] - radius);
  783.             ymax = (GLint) (VB->Win[i][1] + radius);
  784.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  785.  
  786.             red   = VB->Color[i][0];
  787.             green = VB->Color[i][1];
  788.             blue  = VB->Color[i][2];
  789.             s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
  790.             t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
  791.             u = VB->TexCoord[i][2] / VB->TexCoord[i][3];
  792.  
  793.             for (y=ymin;y<=ymax;y++) {
  794.                for (x=xmin;x<=xmax;x++) {
  795.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  796.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  797.                   GLfloat dist2 = dx*dx + dy*dy;
  798.                   if (dist2<rmax2) {
  799.                      alpha = VB->Color[i][3];
  800.                      if (dist2>=rmin2) {
  801.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  802.                         /* coverage is in [0,256] */
  803.                         alpha = (alpha * coverage) >> 8;
  804.                      }
  805.                      alpha = (GLint) (alpha * alphaf);
  806.                      PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s,
  807. t, u );
  808.                   }
  809.                }
  810.             }
  811.             PB_CHECK_FLUSH(ctx,PB)
  812.          }
  813.       }
  814.    }
  815.    else {
  816.       /* Not texture mapped */
  817.       for (i=first;i<=last;i++) {
  818.          if (VB->ClipMask[i]==0) {
  819.             GLint xmin, ymin, xmax, ymax;
  820.             GLint x, y, z;
  821.             GLint red, green, blue, alpha;
  822.  
  823.             dsize=psize*dist_attenuation(ctx,VB->Eye[i]);
  824.             if(dsize>=ctx->Point.Threshold) {
  825.                radius=(MIN2(dsize,ctx->Point.MaxSize)*0.5F);
  826.                alphaf=1.0;
  827.             } else {
  828.                radius=(MAX2(ctx->Point.Threshold,ctx->Point.MinSize)*0.5F);
  829.                dsize/=ctx->Point.Threshold;
  830.                alphaf=(dsize*dsize);
  831.             }
  832.             rmin = radius - 0.7071F;  /* 0.7071 = sqrt(2)/2 */
  833.             rmax = radius + 0.7071F;
  834.             rmin2 = rmin*rmin;
  835.             rmax2 = rmax*rmax;
  836.             cscale = 256.0F / (rmax2-rmin2);
  837.  
  838.             xmin = (GLint) (VB->Win[i][0] - radius);
  839.             xmax = (GLint) (VB->Win[i][0] + radius);
  840.             ymin = (GLint) (VB->Win[i][1] - radius);
  841.             ymax = (GLint) (VB->Win[i][1] + radius);
  842.             z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
  843.  
  844.             red   = VB->Color[i][0];
  845.             green = VB->Color[i][1];
  846.             blue  = VB->Color[i][2];
  847.  
  848.             for (y=ymin;y<=ymax;y++) {
  849.                for (x=xmin;x<=xmax;x++) {
  850.                   GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
  851.                   GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
  852.                   GLfloat dist2 = dx*dx + dy*dy;
  853.                   if (dist2<rmax2) {
  854.                       alpha = VB->Color[i][3];
  855.                      if (dist2>=rmin2) {
  856.                         GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
  857.                         /* coverage is in [0,256] */
  858.                         alpha = (alpha * coverage) >> 8;
  859.                      }
  860.                      alpha = (GLint) (alpha * alphaf);
  861.                      PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha )
  862. ;
  863.                   }
  864.                }
  865.             }
  866.             PB_CHECK_FLUSH(ctx,PB)
  867.          }
  868.       }
  869.    }
  870. }
  871.  
  872.  
  873. /*
  874.  * Examine the current context to determine which point drawing function
  875.  * should be used.
  876.  */
  877. void gl_set_point_function( GLcontext *ctx )
  878. {
  879.    GLboolean rgbmode = ctx->Visual->RGBAflag;
  880.  
  881.    if (ctx->RenderMode==GL_RENDER) {
  882.       if (ctx->NoRaster) {
  883.          ctx->Driver.PointsFunc = null_points;
  884.          return;
  885.       }
  886.       if (ctx->Driver.PointsFunc) {
  887.          /* Device driver will draw points. */
  888.          ctx->Driver.PointsFunc = ctx->Driver.PointsFunc;
  889.       }
  890.       else if (ctx->Point.Params[0]==1.0 && ctx->Point.Params[1]==0.0 && 
  891.                ctx->Point.Params[2]==0.0) { 
  892.          if (ctx->Point.SmoothFlag && rgbmode) {
  893.             ctx->Driver.PointsFunc = antialiased_rgba_points;
  894.          }
  895.          else if (ctx->Texture.Enabled) {
  896.         ctx->Driver.PointsFunc = textured_rgba_points;
  897.          }
  898.          else if (ctx->Point.Size==1.0) {
  899.             /* size=1, any raster ops */
  900.             if (rgbmode)
  901.                ctx->Driver.PointsFunc = size1_rgba_points;
  902.             else
  903.                ctx->Driver.PointsFunc = size1_ci_points;
  904.          }
  905.          else {
  906.         /* every other kind of point rendering */
  907.             if (rgbmode)
  908.                ctx->Driver.PointsFunc = general_rgba_points;
  909.             else
  910.                ctx->Driver.PointsFunc = general_ci_points;
  911.          }
  912.       } 
  913.       else if(ctx->Point.SmoothFlag && rgbmode) {
  914.          ctx->Driver.PointsFunc = dist_atten_antialiased_rgba_points;
  915.       }
  916.       else if (ctx->Texture.Enabled) {
  917.          ctx->Driver.PointsFunc = dist_atten_textured_rgba_points;
  918.       } 
  919.       else {
  920.          /* every other kind of point rendering */
  921.          if (rgbmode)
  922.             ctx->Driver.PointsFunc = dist_atten_general_rgba_points;
  923.          else
  924.             ctx->Driver.PointsFunc = dist_atten_general_ci_points;
  925.      }
  926.    }
  927.    else if (ctx->RenderMode==GL_FEEDBACK) {
  928.       ctx->Driver.PointsFunc = feedback_points;
  929.    }
  930.    else {
  931.       /* GL_SELECT mode */
  932.       ctx->Driver.PointsFunc = select_points;
  933.    }
  934.  
  935. }
  936.  
  937.